//
// Created by haoy on 2017/3/13.
//

#ifndef ANALYZER_PACKET_HPP
#define ANALYZER_PACKET_HPP

#include <algorithm>
#include <ostream>

#include "media.h"
#include "rtp.h"

class CodecRegistry {
public:
    uint32_t getChannelsForPT(uint8_t pt) {
        if (_pt2channels.count(pt)) {
            return _pt2channels[pt];
        }
        return 0;
    }

    uint32_t getSampleRateForPT(uint8_t pt) {
        if (_pt2samplerate.count(pt)) {
            return _pt2samplerate[pt];
        }
        return 0;
    }

    MediaFrame::Type getMediaTypeForPT(uint8_t pt) {
        if (_pt2mt.count(pt)) {
            return _pt2mt[pt];
        }
        return MediaFrame::Audio;
    }

    const std::string& getCodecNameForPT(uint8_t pt) {
        if (_pt2name.count(pt)) {
            return _pt2name[pt];
        }
        return std::string();
    }

    void addCodec(uint8_t pt, const std::string& name, MediaFrame::Type mt, uint32_t samplerate, uint32_t channels) {
        _pt2mt[pt] = mt;
        _pt2samplerate[pt] = samplerate;
        _pt2channels[pt] = channels;
        _pt2name[pt] = name;
    }

    void clear() {
        _pt2mt.clear();
        _pt2samplerate.clear();
        _pt2channels.clear();
        _pt2name.clear();
    }
private:
    std::map<uint8_t, MediaFrame::Type> _pt2mt;
    std::map<uint8_t, uint32_t> _pt2samplerate;
    std::map<uint8_t, uint32_t> _pt2channels;
    std::map<uint8_t, std::string> _pt2name;
};


class PacketHandler {
public:
    virtual void onCodecRegistry(CodecRegistry& codecs, uint8_t pt) = 0;
    virtual void onAudioPacket(RTPPacket* packet, uint64_t pts) = 0;
    virtual void onVideoPacket(RTPPacket* packet, uint64_t pts) = 0;
    virtual void onEnd() = 0;
};

extern std::ostream& operator<< (std::ostream& os, const RTPPacket* p);
extern std::ostream& operator<< (std::ostream& os, const RTPHeader& h);
#endif //ANALYZER_PACKET_HPP
